package com.yvan.leto.server.utils;

import com.google.common.collect.Lists;
import com.yvan.leto.server.domain.ReleaseVo;
import com.yvan.leto.server.security.JwtHelper;
import com.yvan.platform.JsonWapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.CommitCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.joda.time.DateTime;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

@Slf4j
public class GitUtils {

    public static void treeOfStatus(Git git) throws GitAPIException {
        Status status = git.status().call();
        //被删除、被修改，都在 getUncommittedChanges
        System.out.println("Git UncommittedChanges: " + status.getUncommittedChanges());
        //新添加的在 getUntracked
        System.out.println("Git Untracked: " + status.getUntracked());
    }

    /**
     * 列出指定版本的快照文件内容
     */
    public static void fileContentOfRevision(Git git, String revision, String pathString) throws IOException {
        final Repository repository = git.getRepository();
        RevWalk walk = new RevWalk(repository);
        ObjectId objectId = repository.resolve(revision);

        RevCommit revCommit = walk.parseCommit(objectId);
        RevTree revTree = revCommit.getTree();

        TreeWalk treeWalk = TreeWalk.forPath(repository, pathString, revTree);
        byte[] bytes = repository.open(treeWalk.getObjectId(0)).getBytes();
        System.out.println(new String(bytes));
    }

    /**
     * 获取提交日志
     */
    @SneakyThrows
    public static List<ReleaseVo> listCommitLog(Git git, Pagination pagination) {
        Iterator<RevCommit> revCommitIterator = git.log().call().iterator();
        List<ReleaseVo> r = Lists.newArrayList();
        int i = 0;
        int c = 0;
        while (revCommitIterator.hasNext()) {
            RevCommit commit = revCommitIterator.next();
            i++;

            if (pagination != null && pagination.getBegin() > i) {
                continue;
            }
            if (pagination != null && pagination.getPageSize() < c) {
                continue;
            }

            ReleaseVo vo = new ReleaseVo();
            vo.setSha(commit.getId().getName());
            vo.setTime(new DateTime(commit.getCommitTime() * 1000L));

            final String msg = commit.getShortMessage();
            try {
                JsonWapper jw = new JsonWapper(msg);
                //vo.setEnv(jw.asStr("env"));
                //vo.setProject(jw.asStr("project"));
                //vo.setSegment(jw.asStr("segment"));
                vo.setOper(jw.asStr("oper"));
            } catch (Exception e) {
                vo.setMsg(msg);
                vo.setOper(commit.getAuthorIdent().getName());
            }

            r.add(vo);
            c++;
        }
        if (pagination != null) {
            pagination.setCount(i);
        }
        return r;
    }

    /**
     * 获取某次 tree 快照
     */
    @SneakyThrows
    public static void treeOfRevision(Git git, String revision) {
        final Repository repository = git.getRepository();
        ObjectId objectId = repository.resolve(revision);
        RevCommit commit = new RevWalk(repository).parseCommit(objectId);
        RevTree tree = commit.getTree();

        TreeWalk treeWalk = new TreeWalk(repository);
        treeWalk.addTree(tree);
        treeWalk.setRecursive(true);
        while (treeWalk.next()) {
            System.out.println("found: " + treeWalk.getPathString());
        }
    }

    /**
     * 获取当前最新版的 tree
     */
    public static void treeOfHead(Repository repository) throws IOException {
        Ref head = repository.exactRef("HEAD");
        RevWalk walk = new RevWalk(repository);

        RevCommit commit = walk.parseCommit(head.getObjectId());
        RevTree tree = commit.getTree();
        System.out.println("Having tree: " + tree);

        TreeWalk treeWalk = new TreeWalk(repository);
        treeWalk.addTree(tree);
        treeWalk.setRecursive(true);
        while (treeWalk.next()) {
            System.out.println("found: " + treeWalk.getPathString());
        }
    }

    @SneakyThrows
    public static String commitWorkfolder(Git git, String msg) {

        Status status = git.status().call();
        if (status.getUntracked().size() + status.getUncommittedChanges().size() <= 0) {
            //没有文件被修改，不需要提交
            ObjectId head = git.getRepository().exactRef("HEAD").getObjectId();
            return head.getName();
        }

        AddCommand addCommand = git.add();
        addCommand.addFilepattern(".").call();

        CommitCommand commit = git.commit();
        commit.setCommitter(JwtHelper.getLoginName(), "");
        commit.setAuthor(JwtHelper.getLoginName(), "");
        commit.setAll(true);

        RevCommit revCommit = commit.setMessage(msg).call();
        return revCommit.getId().name();
    }
}
